package com.umfwechat.lightprogram.controller.my;

import java.io.File;
import java.math.BigDecimal;
import java.net.URL;
import java.net.URLDecoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.umfwechat.common.code.RetCode;
import com.umfwechat.common.constant.CommonConsts;
import com.umfwechat.common.constant.ValueConsts;
import com.umfwechat.common.prop.UmfPropModel;
import com.umfwechat.lightprogram.vo.SetAgentMerAccstatCust;
import com.umfwechat.util.DateTimesUtil;
import com.umfwechat.util.EmailXmlUtil;
import com.umfwechat.util.ExcelExportSXXSSF;
import com.umfwechat.util.ReqMessageUtil;
import com.umfwechat.util.StringUtil;
import com.umfwechat.util.email.MailSenderInfo;
import com.umfwechat.util.email.SendMailUtil;
import com.umpay.sp.model.common.ReqMessage;
import com.umpay.sp.model.common.ResMessage;
import com.umpay.sp.model.saas.SetAgentMerAccstat;
import com.umpay.sp.model.saas.StoreInf;
import com.umpay.sp.service.saas.remote.SetAgentMerAccstatServiceRemote;
import com.umpay.sp.service.saas.remote.StoreInfServiceRemote;
import com.umpay.sp.xml.XmlData;
/**
 * 分润明细结果发送邮件
 * @author llb
 *
 */
@Controller
@RequestMapping("/agentProfit")
public class SendProfitEmailController {
	private static Logger logger = LoggerFactory.getLogger(SendProfitEmailController.class);
	//分润明细结果发送邮件
	@Resource
	private SetAgentMerAccstatServiceRemote setAgentMerAccstatServiceRemote;
	@Resource
	private StoreInfServiceRemote storeInfServiceRemote;
//	@Resource
//	private MerInfoServiceRemote merInfoService;
	@RequestMapping("/sendBillEmail")
	@ResponseBody
	public JSONObject sendBillEmail (HttpServletRequest request, HttpServletResponse response){
		JSONObject resJson= new JSONObject();
		resJson.put(CommonConsts.RETCODE, RetCode.SUCCESS);
		resJson.put(CommonConsts.RETMSG, "分润明细邮件将在3-5分钟后送达，请注意查收");
		//通过流的方式获取前端的参数
		String reqJSON=  (String) request.getAttribute(CommonConsts.REQUESTDATA);
		JSONObject json = null;
		try {
			json = JSONObject.fromObject(reqJSON);
		} catch (Exception e) {
			resJson.put(CommonConsts.RETCODE, "0001");
			resJson.put(CommonConsts.RETMSG, "获取请求参数失败");
			logger.info("【非pos分润详情查询】----#---------#--获取请求参数失败异常--#---------#--" + e);
			return resJson;
		}
		String loginAgentId=json.optString(CommonConsts.LOGINAGENTID);//代理商编号
		String date=json.optString(CommonConsts.DATE);//日期2017-07
		String types=json.optString(CommonConsts.TYPES);//代理商类型
		String agentId=json.optString(CommonConsts.AGENTID,loginAgentId);//代理商编号
		String storeId=json.optString(CommonConsts.STOREID);//店铺编号
		String email=json.optString("email");//邮箱
		//*********************************查询数据***********************************************************
		List<SetAgentMerAccstatCust> list =new ArrayList<SetAgentMerAccstatCust>();;
		//查询多级代理商，获取所有下级代理商编号，包含自己代理商编号
		Map<String, Object> resQ = queryAgentRel(agentId, "0");//0或不传-查询完整级别关系,1-查询直接下级,2-查询所有下级,3-查询直接上级,4-查询所有上级
		String retCodeQ=(String)resQ.get("retCode");
		if(!"0000".equals(retCodeQ)){
			json.put(CommonConsts.RETCODE, "0001");
			json.put(CommonConsts.RETMSG, "服务器异常，请稍后再试");
			return json;
		}
		Map<String ,Map<String ,String>> mapDate = (Map<String ,Map<String ,String>>) resQ.get("agentMap");
		Map<String, String> map2 = mapDate.get(agentId);	//获取查询代理商的信息
		String agentLevel =  map2.get("agentLevel");
		Map<String, Object> agentMetaMap =  (Map<String, Object>) resQ.get("agentMetaMap");
		Map<String, List<String>> supAgentLevelRelMap=(Map<String, List<String>>) resQ.get("supAgentLevelRelMap");
		Map<String, Map<String, String>> agentDataList = (Map<String, Map<String, String>>)resQ.get("agentMap");
		Map<String, String> currentAgentData = agentDataList.get(agentId);//当前代理商的基本信息
//		Integer min = Integer.valueOf( agentMetaMap.get("minLevel").toString()) ;
//		Integer max =  Integer.valueOf(agentLevel) ; // agentMetaMap.get("maxLevel").toString()
//		StringBuffer sb = new StringBuffer();//所有代理商编号
//		for(int i = max;i<=min;i++){
//			List<String> listA  = (List<String>) agentMetaMap.get("agent["+i+"]List");
//			for (String s : listA) {
//				sb.append("'"+s+"',");
//			}
//		}
//		String agentIds = sb.substring(0,sb.length()-1);//代理商集合
		String agentIds = "'"+agentId+"'";//代理商集合
		Calendar calendar= Calendar.getInstance();
		calendar.set(Calendar.YEAR, Integer.parseInt(date.substring(0, 4)));
		calendar.set(Calendar.MONTH, Integer.parseInt(date.substring(5, 7))-1);
		calendar.set(Calendar.DATE, 1);
		Date time = calendar.getTime();
		SimpleDateFormat sd=new SimpleDateFormat(DateTimesUtil.formatDay8Str);
		String startDate = sd.format(time);
		int daysOfMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
		calendar.set(Calendar.DATE, daysOfMonth);
		Date time2 = calendar.getTime();
		String endDate = sd.format(time2);
		//根据代理商编号查询所有店铺编号
		String pageNo =json.optString(CommonConsts.PAGE_NO, ValueConsts.PAGE_ONE);	//当前页
		String pageSize = json.optString(CommonConsts.PAGE_SIZE, ValueConsts.PAGE_TWENTY);	//每页条数
//		Integer startNo = Integer.valueOf(pageSize)*(Integer.valueOf(pageNo)-1);	//计算开始行数
//		Integer endNo = Integer.valueOf(pageSize)*Integer.valueOf(pageNo);	//计算结束行数
		ReqMessage req2 = ReqMessageUtil.makeSpReq();
		//向service发送的请求数据
		req2.put(XmlData.AGENTID_S, agentIds);//代理商编号
		req2.put(CommonConsts.START_DATE, startDate);//开始日期
		req2.put(CommonConsts.END_DATE, endDate);//结束日期
		req2.put(CommonConsts.TYPES, types);//代理商类型
		if(StringUtil.isNotEmpty(storeId)){
			req2.put(CommonConsts.MERIDS, "'"+storeId+"'");//店铺编号
		}
//		req2.put(CommonConsts.START_NO,startNo.toString());
//		req2.put(CommonConsts.END_NO,endNo.toString());
		ResMessage resMessage = null;
		try {
			//调用查询分润分摊统计信息接口
			logger.info("【非pos分润详情查询接口】入参："+req2.toString());
			resMessage = setAgentMerAccstatServiceRemote.getAccstatByMerIdAndDate(req2);
			logger.info("【非pos分润详情查询接口】出参："+resMessage.toString());
		} catch (Exception e) {
			resJson.put(CommonConsts.RETCODE, "0001");
			resJson.put(CommonConsts.RETMSG, "查询分润分摊统计信息异常，请稍后重试");
			logger.info("【非pos分润详情查询】调用查询分润分摊统计信息异常失败："+e);
			return resJson;
		}
		//判断返回码是否是0000
		String code = resMessage.getRetCode();
		if (code.equals(RetCode.SUCCESS)) {
			List<SetAgentMerAccstat> accstatList = (List<SetAgentMerAccstat>) resMessage.getResMap().get(CommonConsts.SETAGENTMERACCSTATLIST);
			if(accstatList != null){
				List<String> listStoreId= new ArrayList<String>();
				for (SetAgentMerAccstat setAgentMerAccstat : accstatList) {
					if(!listStoreId.contains(setAgentMerAccstat.getMerId())){	//没有包含
						listStoreId.add(setAgentMerAccstat.getMerId());
						SetAgentMerAccstatCust accstatVo= new SetAgentMerAccstatCust();
						accstatVo.setStoreId(setAgentMerAccstat.getMerId());
//						//根据店铺编号查询店铺名称
//						ReqMessage reqFind = ReqMessageUtil.makeSpReq();
//						ResMessage merInfoResForSearch =null;
//						reqFind.put("merId",setAgentMerAccstat.getMerId());
//						try {
//							logger.info("【根据店铺编号查询店铺信息接口】入参："+reqFind.toString());
//							merInfoResForSearch = merInfoService.getMerInfoAndMerExInfo(reqFind);
//							logger.info("【根据店铺编号查询店铺信息接口】出参："+merInfoResForSearch);
//						} catch (Exception e) {
//							resJson.put(CommonConsts.RETCODE, "00434101");
//							resJson.put(CommonConsts.RETMSG, "服务器异常，请稍后再试");
//							logger.info("【查询店铺详情接口】异常："+e);
//							return resJson;
//						}
//						// 获取商户信息和扩展成功后
//						if (!"0000".equals(merInfoResForSearch.getRetCode())) {
//							resJson.put(CommonConsts.RETCODE, "00434101");
//							resJson.put(CommonConsts.RETMSG, "服务器异常，请稍后再试");
//							return resJson;
//						}
//						MerInfo merInfo = (MerInfo) merInfoResForSearch.getValue("merInfo");
//						accstatVo.setStoreName(merInfo==null ? "" :merInfo.getMerName());
//						String currentAgentId = setAgentMerAccstat.getAgentId();
//						accstatVo.setAgentId(currentAgentId);//代理商编号
//						List<String> currentAgentIdList =null;
						//一级代理商没有上级
//						if(!currentAgentId.startsWith("Y") && !"".equals(currentAgentId)){
//							currentAgentIdList = supAgentLevelRelMap.get(currentAgentId);
//						}
//						accstatVo.setUpAgentId(currentAgentIdList==null ? "" : currentAgentIdList.get(0)) ;//上级代理商编号
						
						ReqMessage reqStore = ReqMessageUtil.makeSpReq();
						reqStore.put(CommonConsts.STOREID, setAgentMerAccstat.getMerId());
						ResMessage resStore =null;
						try {
							logger.info("【根据店铺编号查询店铺信息接口】入参："+reqStore.toString());
							resStore = storeInfServiceRemote.getStoreInfByPri(reqStore);	//根据店铺编号查询店铺信息
							logger.info("【根据店铺编号查询店铺信息接口】出参："+resStore);
						} catch (Exception e1) {
							resJson.put(CommonConsts.RETCODE, "0001");
							resJson.put(CommonConsts.RETMSG,"查询店铺详情接口异常");
							logger.info("【查询店铺详情接口】异常："+e1);
							return resJson;
						}
						String retCodeStore = resStore.getRetCode();
						StoreInf storeInf =null;
						if(retCodeStore.equals(RetCode.SUCCESS)){
							storeInf = (StoreInf) resStore.getResMap().get(CommonConsts.STOREINF);
							if(storeInf==null){
								storeInf =new StoreInf();
								storeInf.setStoreShortName("");
								storeInf.setAgentId("");
							}
						}else{
							resJson.put(CommonConsts.RETCODE, "00434101");
							resJson.put(CommonConsts.RETMSG, "服务器异常，请稍后再试");
							return resJson;
						}
						accstatVo.setStoreName(storeInf.getStoreShortName());
						String currentAgentId = storeInf.getAgentId();
						accstatVo.setAgentId(currentAgentId);//代理商编号
						List<String> currentAgentIdList =null;
						//一级代理商没有上级
						if(!"".equals(currentAgentId) && !currentAgentId.startsWith("Y")){
							currentAgentIdList = supAgentLevelRelMap.get(currentAgentId);
						}
						accstatVo.setUpAgentId(currentAgentIdList==null ? "" : currentAgentIdList.get(0)) ;//上级代理商编号
						accstatVo.setAmount(new BigDecimal(setAgentMerAccstat.getAmount()).divide(new BigDecimal(100)).toString());
						
						accstatVo.setPtAmount(new BigDecimal(setAgentMerAccstat.getPtAmount()).divide(new BigDecimal(100)).toString());
						accstatVo.setProfitAmt(new BigDecimal(setAgentMerAccstat.getProfitAmt()).divide(new BigDecimal(100)).toString());
						
						accstatVo.setTtamount(new BigDecimal(setAgentMerAccstat.getTtAmount()).divide(new BigDecimal(100)).toString()) ;
						accstatVo.setFullProfitAmt(new BigDecimal(setAgentMerAccstat.getFullProfitAmt()).divide(new BigDecimal(100)).toString()) ;
						
						accstatVo.setTransnum(setAgentMerAccstat.getTransNum()) ;
						accstatVo.setUncapsAmt(new BigDecimal(setAgentMerAccstat.getUncapsAmt()).divide(new BigDecimal(100)).toString()) ;
						
						accstatVo.setPtnum(setAgentMerAccstat.getPtNum()) ;
						accstatVo.setCapSunreacAmt(new BigDecimal(setAgentMerAccstat.getCapSunreachAmt()).divide(new BigDecimal(100)).toString()) ;
						
						accstatVo.setTtnum(setAgentMerAccstat.getTtNum()) ;
						accstatVo.setCapSreachedAmt(new BigDecimal(setAgentMerAccstat.getCapSreachedAmt()).divide(new BigDecimal(100)).toString()) ;
						
						list.add(accstatVo);
					}else{	//包含了,就叠加
						for (SetAgentMerAccstatCust accstatVo : list) {
							if(accstatVo.getStoreId().equals(setAgentMerAccstat.getMerId())){
								BigDecimal amount = new BigDecimal(accstatVo.getAmount());	//总交易额（元）
								BigDecimal ptAmount = new BigDecimal(accstatVo.getPtAmount());
								BigDecimal profitAmt = new BigDecimal(accstatVo.getProfitAmt());
								
								BigDecimal ttamount = new BigDecimal(accstatVo.getTtamount());	//退费交易额
								BigDecimal fullProfitAmt = new BigDecimal(accstatVo.getFullProfitAmt());	//总分润金额
								
								Integer transnum = Integer.parseInt(accstatVo.getTransnum());	//总交易笔数
								BigDecimal uncapsAmt = new BigDecimal(accstatVo.getUncapsAmt());	//非封顶分润金额
								
								Integer ptnum = Integer.parseInt(accstatVo.getPtnum());
								BigDecimal capSunreacAmt = new BigDecimal(accstatVo.getCapSunreacAmt());	//封顶未达分润金额
								
								Integer ttnum = Integer.parseInt(accstatVo.getTtnum());	//退款交易笔数
								BigDecimal capSreachedAmt = new BigDecimal(accstatVo.getCapSreachedAmt());
								
								amount.add(new BigDecimal(setAgentMerAccstat.getAmount()).divide(new BigDecimal(100)));
								accstatVo.setAmount(amount.toString());
								
								String ptAmount2 = setAgentMerAccstat.getPtAmount();
								ptAmount.add(new BigDecimal(ptAmount2).divide(new BigDecimal(100)));
								accstatVo.setPtAmount(ptAmount.toString());
								
								String profitAmt2 = setAgentMerAccstat.getProfitAmt();
								profitAmt.add(new BigDecimal(profitAmt2).divide(new BigDecimal(100)));
								accstatVo.setProfitAmt(profitAmt.toString());
								
								String fullProfitAmt2 = setAgentMerAccstat.getFullProfitAmt();
								fullProfitAmt.add(new BigDecimal(fullProfitAmt2).divide(new BigDecimal(100)));
								accstatVo.setFullProfitAmt(fullProfitAmt.toString());
								
								String ttAmount2 = setAgentMerAccstat.getTtAmount();
								ttamount.add(new BigDecimal(ttAmount2).divide(new BigDecimal(100)));
								accstatVo.setTtamount(ttamount.toString());
								
								String uncapsAmt2 = setAgentMerAccstat.getUncapsAmt();
								uncapsAmt.add(new BigDecimal(uncapsAmt2).divide(new BigDecimal(100)));
								accstatVo.setUncapsAmt(uncapsAmt.toString());
								
								String transNum2 = setAgentMerAccstat.getTransNum();
								transnum+=Integer.valueOf(transNum2);
								accstatVo.setTransnum(transnum.toString());
								
								String capSunreachAmt2 = setAgentMerAccstat.getCapSunreachAmt();
								capSunreacAmt.add(new BigDecimal(capSunreachAmt2).divide(new BigDecimal(100)));
								accstatVo.setCapSunreacAmt(capSunreacAmt.toString());
								
								String ttNum2 = setAgentMerAccstat.getTtNum();
								ttnum+=Integer.valueOf(ttNum2);
								accstatVo.setTtnum(ttnum.toString());
								
								String ptNum2 = setAgentMerAccstat.getPtNum();
								ptnum+=Integer.valueOf(ptNum2);
								accstatVo.setPtnum(ptnum.toString());
								
								String capSreachedAmt2 = setAgentMerAccstat.getCapSreachedAmt();
								capSreachedAmt.add(new BigDecimal(capSreachedAmt2).divide(new BigDecimal(100)));
								accstatVo.setCapSreachedAmt(capSreachedAmt.toString());
								
								break;
							}
						}
					}
				}
				//对list进行排序
				Collections.sort(list, new Comparator<SetAgentMerAccstatCust>(){

					@Override
					public int compare(SetAgentMerAccstatCust o1,
							SetAgentMerAccstatCust o2) {
						if(Double.parseDouble(o1.getFullProfitAmt())>Double.parseDouble(o2.getFullProfitAmt())){
							return -1;
						}else{
							return 1;
						}
					}
				} );
			}//没有交易记录就不存值
		} else {
			resJson.put(CommonConsts.RETCODE, "0001");
			resJson.put(CommonConsts.RETMSG, resMessage.getRetMsg());
			return resJson;
		}
		logger.info("【非pos分润明细】数据结果"+list.toString());
		System.out.println("【非pos分润明细】数据结果"+list.toString());
		//*********************************生成Excel***********************************************************
		//导出文件存放的路径，并且是虚拟目录指向的路径，在web服务器
		String filePathUrl = UmfPropModel.INSTANCE.getPropValue("profit.excel.path");
		String filePath=filePathUrl.replace("{yyyyMM}", startDate.substring(0, 6));
		String filename=null;
		String format=date;
		try {
			filename = exportExcel(date, agentId, list, filePath);
			Date formatDate = new SimpleDateFormat("yyyy-MM").parse(date);
			System.out.println(formatDate);
			format = new SimpleDateFormat("yyyy年MM月").format(formatDate);
		} catch (ParseException e) {
			logger.info("获取邮件失败",e);
			resJson.put(CommonConsts.RETCODE, "0001");
			resJson.put(CommonConsts.RETMSG, "获取邮件失败");
			return resJson;
		} catch (Exception e) {
			logger.info("获取邮件失败",e);
			resJson.put(CommonConsts.RETCODE, "0001");
			resJson.put(CommonConsts.RETMSG, "获取邮件失败");
			return resJson;
		}
		//*********************************发送邮件***********************************************************
		//邮件内容模板
		String profitTemplateEmailUrl=UmfPropModel.INSTANCE.getPropValue("profitTemplateEmailUrl");
		File zipFile = new File(filePath+File.separatorChar+filename);
		List<File> fileList = new ArrayList<File>();
		fileList.add(zipFile);
		//发邮件
		
		String mailto = email;
		String subject = format+"分润明细("+agentId+")"; //
		//邮件内容
		Calendar calendar2 = Calendar.getInstance();
		String currentDate = DateTimesUtil.date8(calendar2.getTime());
		Map<String, String> map = new HashMap<String, String>();
		map.put("agentShortName", currentAgentData.get("agentShortName"));
		map.put(CommonConsts.AGENTID, agentId);
		map.put(CommonConsts.DATE, format);
		map.put(CommonConsts.YYYY, currentDate.substring(0,4));
		map.put(CommonConsts.MM, currentDate.substring(4,6));
		map.put(CommonConsts.DD, currentDate.substring(6,8));
		MailSenderInfo mailSenderInfo = new MailSenderInfo();
		mailSenderInfo.setToAddress(mailto);
		EmailXmlUtil.emailXmlRead(profitTemplateEmailUrl, mailSenderInfo, map);
		String mailContent = mailSenderInfo.getContent();
		for (String s : map.keySet()) {
			mailContent = mailContent.replaceAll(s, map.get(s));
		}
		SendMailUtil.sendMail(mailto, subject, mailContent, fileList);
		logger.info("【发送邮件结束】" + DateTimesUtil.date(DateTimesUtil.formatTime16Str));
		return resJson;
	}
	private String exportExcel(String date, String agentId,
			List<SetAgentMerAccstatCust> list, String filePath) throws Exception {
		File filePathFile=new File(filePath);
		if(!filePathFile.exists()){
			filePathFile.mkdirs();
		}
		//导出文件的前缀
		String filePrefix=agentId+"_"+date+"月份的分润明细";
		
		URL url = SendProfitEmailController.class.getClassLoader().getResource("template/agentProfitDetail.xlsx");//   /C:\\Users\\john\\Desktop
		String syspath = URLDecoder.decode(url.getPath());
		
		//告诉导出类数据list中对象的属性，让ExcelExportSXXSSF通过反射获取对象的值
		List<String> fieldCodes=new ArrayList<String>();
		fieldCodes.add("num");
		fieldCodes.add("storeName");
		fieldCodes.add("storeId");
		fieldCodes.add("profitAmt");
		fieldCodes.add("fullProfitAmt");
		fieldCodes.add("amount");
		
		fieldCodes.add("transnum");
		fieldCodes.add("ptAmount");
		fieldCodes.add("ttamount");
		fieldCodes.add("ptnum");//
		fieldCodes.add("ttnum");//
		
		fieldCodes.add("uncapsAmt");//
		fieldCodes.add("capSunreacAmt");//
		fieldCodes.add("capSreachedAmt");//
		fieldCodes.add("agentId");//
		fieldCodes.add("upAgentId");//
		

		//开始导出，执行一些workbook及sheet等对象的初始创建
		ExcelExportSXXSSF excelExportSXXSSF = ExcelExportSXXSSF.start(filePath, "/upload/", filePrefix, fieldCodes, syspath);
		//执行导出
		excelExportSXXSSF.writeDatasByObject(list);
		//向磁盘输出文件，返回下载文件的http地址
		String filename = excelExportSXXSSF.exportFile();
		System.out.println(filename);
		return filename;
	}
	private Map<String, Object> queryAgentRel(String agentId,String type) {
		Map<String, Object> req = ReqMessageUtil.makeReqCrmMap();
	    req.put("agentId", agentId);
	    req.put("relType", type);
		Map<String, Object> res = null;
		try {
			XStream xstream = new XStream(new DomDriver());
			// URL配置文件取
			String url=UmfPropModel.INSTANCE.getPropValue("agent.crm.queryAgentRel");
			//调用受理注销用户标识接口
			logger.info("【查询代理商多级关系接口】入参：" + req.toString()+"请求路径url="+url);
			res =  (Map<String, Object>) com.umfwechat.util.HttpUtil.getResObjPost(url, xstream, req);	
		} catch (Exception e) {
			logger.info("【调用查询代理商多级关系接口失败!】",e);
			res.put(CommonConsts.RETCODE, "0001");
			res.put(CommonConsts.RETMSG,"服务器异常，请稍后再试");	
			return res;
		}
		if(res==null){
			res.put(CommonConsts.RETCODE, "0001");
			res.put(CommonConsts.RETMSG, "服务器异常，请稍后再试");
			return res;
		}
		logger.info("【查询代理商多级关系接口】出参：" + res.toString());				
		return res;
	}
	public static void main(String[] args) throws Exception {
		SendProfitEmailController controller= new SendProfitEmailController();
		controller.sendBillEmail(null, null);
	}
}
